package myJs.user.data

import japgolly.scalajs.react._
import japgolly.scalajs.react.component.Scala.BackendScope
import myJs.Implicits._
import myJs.Utils._
import scala.scalajs.js.Dynamic.{global=>g}
import myJs.myPkg.jquery._
import myJs.myPkg._
import myJs.tool.Tool
import myJs.tool.Tool._
import org.scalajs.dom._
import org.scalajs.dom.ext.Ajax
import scalatags.Text.{TypedTag, all}
import shared.VarTool
import shared.Pojo._

import scala.collection.SeqMap
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.{Date, JSON}
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.tool.Pojo.FilterContentData
import japgolly.scalajs.react.vdom.all.{s, _}
import japgolly.scalajs.react._
import japgolly.scalajs.react.component.Scala
import japgolly.scalajs.react.component.Scala.BackendScope
import japgolly.scalajs.react.vdom.HtmlTags
import myJs.components.TagComponent
import org.scalajs.dom.raw.HTMLImageElement

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("DataManage")
object DataManage {
  val formId = "form"
  val tableId = "table"
  val updateFormId = "updateForm"
  val updateModalId = "updateModal"
  val viewModalId = "viewModal"
  val timeFieldNames = List("uploadTime")
  val groupTabId = "group"
  val metDataTabId = "metData"
  val dataManageId = "dataManage"

  @JSExport("init")
  def init = {

//        selectTab("lib")

    refreshTag
    MetDataTab.init
    GroupTab.init
    VarInfoTab.init
    BiomTab.init
    FileViewModal.init

    refreshTable()

    $("a[data-toggle='tab']").on("show.bs.tab", (y: Element, e: Event) => {
      val tabId = $(y).attr("href").get
      tabId match {
        case x if List("#file", "#groupFile").contains(x) => tabValidator("file")
        case x if List("#hand", "#groupHand").contains(x) => tabValidator("fileContent")
        case _ =>
      }
    })

    $(".myMainUl a[data-toggle='tab']").on("shown.bs.tab", (y: Element, e: Event) => {
      refreshTable()
    })

    registerEvent

//    addShow

  }

  def selectTab(tabId: String) = {
    $(".myMainUl >li").removeClass("active")
    $(s".myMainUl").find(s"a[href='#${tabId}']").parent("li").addClass("active")
    $(s"#${tabId}").siblings().removeClass("active in")
    $(s"#${tabId}").addClass("active in")
  }

  def refreshTag = {
    val tagElements = document.querySelectorAll(".tag")
    TagComponent.Component().renderIntoDOM(tagElements)
  }

  def registerEvent = {
    tableFilterEvent
  }

  def tableFilterEvent = {
    Tool.clickHide
    $(s"#${dataManageId} .myOperate").on("click", (y: Element) => {
      filterContentShow(y)
    })
    $(s"#${dataManageId} .mySortLi").on("click", (y: Element) => {
      val parentId =s"${dataManageId} #${Tool.getCurTabId}"
      Tool.execSort(y, parentId, () => {
        refreshTable()
      })
    })
    $(s"#${dataManageId} .myConfirm").on("click", (y: Element) => {
      val parentId =s"${dataManageId} #${Tool.getCurTabId}"
      Tool.confirmFilter(y, parentId, () => {
        refreshTable()
      })
    })
    $(s"#${dataManageId} .myHide").on("click", (y: Element) => {
      val parentId =s"${dataManageId} #${Tool.getCurTabId}"
      Tool.hideFilterContent(y)
    })
    $(document.body).on("click", s"#${dataManageId} .myRemove", "", (y: Element) => {
      val parentId =s"${dataManageId} #${Tool.getCurTabId}"
      Tool.removeCondition(y, parentId, () => {
        refreshTable()
      })
    })
    $(document.body).on("click", s"#${dataManageId} .myRemoveSort", "", (y: Element) => {
      val parentId =s"${dataManageId} #${Tool.getCurTabId}"
      Tool.removeSort(y, parentId, () => {
        refreshTable()
      })
    })
  }

  def initFilterContent(tabId: String = "") = {
    val textSortDatas = List(
      FilterContentData("fileName", messages("fileName")),
      FilterContentData("comment", messages("comment")),
    )
    val sortDatas = List(
      FilterContentData("size", messages("size"), List("", "0KB-100KB", "100KB-1MB", "1MB-10MB")),
      FilterContentData("tags", messages("tag"), "" :: Tool.tagMap.valueList)
    )
    val timeSortDatas = List(
      FilterContentData("uploadTime", messages("uploadModifyTime"))
    )
    Tool.initFilterContent(textSortDatas = textSortDatas, sortDatas = sortDatas, timeSortDatas = timeSortDatas,
      parentId = s"${tabId}")
  }

  @JSExport("filterContentShow")
  def filterContentShow(y: Element) = {
    val tabId = Tool.getCurTabId
    $(".filterContent").hide()
    val fieldName = Tool.getFilterDataFieldName(y)
    val contentId = s"#${tabId} #${fieldName}Content"
    val contentPaddingTop = $(".page-content").css("padding-top").replaceAll("px$", "").toInt
    val yTop = $(y).offset().top - $(".page-header").height() - contentPaddingTop + $(y).height() + 2
    val pageWidth = document.body.clientWidth
    val yTotalLeft = $(y).offset().left
    val leftWidth = $("#myLeft").width()
    val yLeft = yTotalLeft - leftWidth
    val width = 210
    val trueYLeft = if (yTotalLeft + width > pageWidth) pageWidth - leftWidth - 220 - 6 else yLeft - 3
    $(s"${contentId}").css("top", yTop.toInt).css("left", trueYLeft.toInt).width(width)
    $(s"${contentId}").show()
  }

  def showExample = {
    val name="fileContent"
    val tabId = Tool.getCurTabId
    val url = g.jsRoutes.controllers.DataController.getFileContent().url.toString
    val fileName = tabId match {
      case x if x == groupTabId => "group.txt"
      case x if x == VarInfoTab.tabId => VarInfoDataKind.defaultFileName
      case x if x == BiomTab.tabId => BiomDataKind.defaultFileName
      case _ => "met_data.txt"
    }
    Ajax.get(url = s"${url.noCache}&fileName=${fileName}", headers = Map("Content-Type" -> "application/json")).
      map { xhr =>
        val rs = xhr.responseText
        val finalRs=rs.split("\n").take(10).mkString("\n")
        $(s"#${tabId} textarea[name='${name}']").`val`(finalRs)
        $(s"#${tabId} #${formId}").bv.revalidateField(name)
      }
  }

  def tabValidator(enField: String) = {
    val tabId = Tool.getCurTabId
    List("file", "fileContent").foreach { fieldName =>
      val bv = $(s"#${tabId} #${formId}").bv
      if (enField != fieldName) {
        bv.enableFieldValidators(fieldName, false)
      } else {
        bv.enableFieldValidators(fieldName, true)
      }
    }
  }

  @JSExport("delete")
  def delete(id: String) = {
    val options = SwalOptions(
      title = "",
      text = messages("deleteConfirm"),
      `type` = "warning",
      showCancelButton = true,
      showConfirmButton = true,
      confirmButtonClass = Tool.confirmButtonClass,
      confirmButtonText = messages("confirm"),
      closeOnConfirm = false,
      cancelButtonText = messages("cancel"),
      showLoaderOnConfirm = true,
      cancelButtonClass = Tool.cancelButtonClass
    )
    Swal.swal(options, () => {
      val url = g.jsRoutes.controllers.DataController.deleteFileDataById().url.toString
      Ajax.delete(url = s"${url}?id=${id}").map { xhr =>
        refreshTable { () =>
          val options = SwalOptions(
            `type` = "success",
            title = messages("success"),
            text = messages("deleteSuccessfully")
          )
          Swal.swal(options)
        }
      }
    })
  }

  def refreshTable(f: () => js.Any = () => ()) = {
    val tabId = Tool.getCurTabId
    val execF = tabId match {
      case x if x == metDataTabId => MetDataTab.refreshTable()
      case x if x == groupTabId => GroupTab.refreshTable()
      case x if x == VarInfoTab.tabId => VarInfoTab.refreshTable()
      case x if x == BiomTab.tabId => BiomTab.refreshTable()
    }
    execF.map { data =>
      f()
    }
  }

  def sortExec(data: JArJDS, queryMap: Map[String, js.Array[String]]) = {
    val sortOp = queryMap.get("sort").map(_.head)
    val sortData = sortOp.map { sort =>
      val ascSortData = sort match {
        case "size" => data.sortBy(_ (sort).toInt)
        case "tags" =>
          val rs = data.sortWith { (tmpX, tmpY) =>
            val x = Tool.tagMap(tmpX(sort))
            val y = Tool.tagMap(tmpY(sort))
            x.localeCompare(y, "zh-CN") < 0
          }
          rs
        case _ => data.sortBy(_ (sort))
      }
      queryMap("order").head match {
        case "desc" => ascSortData.reverse
        case "asc" => ascSortData
      }
    }.getOrElse(data)
    sortData
  }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case _ => v
  }

  @JSExport("addShow")
  def addShow = {
    val tabId = Tool.getCurTabId
    $(s"#${tabId} #addModal").modal("show")
    showExample
  }

}
